package com.cooperate.fly.web;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.cooperate.fly.bo.BaseNode;
import com.cooperate.fly.bo.Field;
import com.cooperate.fly.bo.Schema;
import com.cooperate.fly.bo.TableWithBLOBs;
import com.cooperate.fly.bo.User;
import com.cooperate.fly.bo.UserGroup;
import com.cooperate.fly.mapper.UserGroupMapper;
import com.google.gson.Gson;

/**
 * Created by Stellar_Lee on 2016/4/18.
 */
@Service("web-front-helper")
public class WebFrontHelper {

    @Value("#{propertiesReader['schema_root_name']}")
    public String schemaRootName;

    @Value("#{propertiesReader['root_node_name']}")
    public String rootNodeName;

    @Value("#{propertiesReader['group_root_name']}")
    public String groupRootName;

    @Value("#{propertiesReader['schema_root_icon']}")
    public String schemaRootIcon;

    @Value("#{propertiesReader['schema_catalog_type']}")
    public int schemaCatalogType;
    @Value("#{propertiesReader['schema_catalog_icon']}")
    public String schemaCatalogIcon;

    @Value("#{propertiesReader['schema_database_type']}")
    public  int schemaDatabaseType;
    @Value("#{propertiesReader['schema_database_icon']}")
    public String schemaDatabaseIcon;

    @Value("#{propertiesReader['field_catalog_type']}")
    public  int fieldCatalogType;
    @Value("#{propertiesReader['field_catalog_icon']}")
    public  String fieldCatalogIcon;

    @Value("#{propertiesReader['field_data_type']}")
    public  int fieldDataType;
    @Value("#{propertiesReader['field_data_icon']}")
    public  String fieldDataIcon;

    @Value("#{propertiesReader['field_data_float_type']}")
    public  int fieldFloatType;
    @Value("#{propertiesReader['field_float_icon']}")
    public  String fieldFloatIcon;

    @Value("#{propertiesReader['field_data_text_type']}")
    public  int fieldTextType;
    @Value("#{propertiesReader['field_text_icon']}")
    public  String fieldTextIcon;

    @Value("#{propertiesReader['field_data_picture_type']}")
    public  int fieldPictureType;
    @Value("#{propertiesReader['field_picture_icon']}")
    public  String fieldPictureIcon;

    @Value("#{propertiesReader['field_data_attach_type']}")
    public  int fieldAttachType;
    @Value("#{propertiesReader['field_attach_icon']}")
    public  String fieldAttachIcon;

    @Value("#{propertiesReader['field_data_matrix_type']}")
    public  int fieldMatrixType;
    @Value("#{propertiesReader['field_matrix_icon']}")
    public  String fieldMatrixIcon;

    @Value("#{propertiesReader['field_data_multi_type']}")
    public  int fieldMultiType;
    @Value("#{propertiesReader['field_multi_icon']}")
    public  String fieldMultiIcon;

    @Value("#{propertiesReader['field_data_3D_type']}")
    public  int field3DType;
    @Value("#{propertiesReader['field_3D_icon']}")
    public  String field3DIcon;

    @Value("#{propertiesReader['field_data_link_type']}")
    public  int fieldLinkType;
    @Value("#{propertiesReader['field_link_icon']}")
    public  String fieldLinkIcon;

    @Value("#{propertiesReader['field_data_time_type']}")
    public  int fieldTimeType;
    @Value("#{propertiesReader['field_time_icon']}")
    public  String fieldTimeIcon;
    @Value("#{propertiesReader['field_data_video_type']}")
    public  int fieldVideoType;
    @Value("#{propertiesReader['field_video_icon']}")
    public  String fieldVideoIcon;
    @Value("#{propertiesReader['field_data_3matrix_type']}")
    public int field3MatrixType;
    @Value("#{propertiesReader['field_3matrix_icon']}")
    public String field3MatrixIcon;


    @Value("#{propertiesReader['field_catalog_name']}")
    public  String fieldCatalogName;
    @Value("#{propertiesReader['field_data_name']}")
    public  String fieldDataName;
    @Value("#{propertiesReader['field_data_float_name']}")
    public  String fieldFloatName;
    @Value("#{propertiesReader['field_data_text_name']}")
    public  String fieldTextName;
    @Value("#{propertiesReader['field_data_picture_name']}")
    public  String fieldPictureName;
    @Value("#{propertiesReader['field_data_matrix_name']}")
    public  String fieldMatrixName;
    @Value("#{propertiesReader['field_data_attach_name']}")
    public  String fieldAttachName;
    @Value("#{propertiesReader['field_data_3D_name']}")
    public  String field3DName;
    @Value("#{propertiesReader['field_data_link_name']}")
    public  String fieldLinkName;
    @Value("#{propertiesReader['field_data_time_name']}")
    public  String fieldTimeName;
    @Value("#{propertiesReader['field_data_video_name']}")
    public  String fieldVideoName;
    @Value("#{propertiesReader['field_data_multi_name']}")
    public  String fieldMultiName;
    @Value("#{propertiesReader['field_data_3matrix_name']}")
    public  String field3MatrixName;
    @Value("#{propertiesReader['schema_database_name']}")
    public  String schemaDatabaseName;

    @Value("#{propertiesReader['case_catalog_type']}")
    public int caseCatalogType;
    @Value("#{propertiesReader['case_data_type']}")
    public int caseDataType;
    @Value("#{propertiesReader['case_catalog_icon']}")
    public String caseCatalogIcon;
    @Value("#{propertiesReader['case_data_icon']}")
    public String caseDataIcon;

    @Value("#{propertiesReader['field_root_node_id']}")
    public int fieldRootNodeId;

    /**
     * 构建树结构，需要传入树的根节点的名称和图标名称
     *
     * @param baseNodes
     * @param checkedIds
     * @param rootNodeName
     * @param rootIcon
     * @return
     */
    public TypeTreeNode buildBaseTree(ArrayList<BaseNode> baseNodes,List<Integer> checkedIds,String rootNodeName,
                                             String rootIcon){
        Logger log=Logger.getLogger(WebFrontHelper.class);
        Map<Integer,TypeTreeNode> nodesMap=new LinkedHashMap<Integer, TypeTreeNode>();
        TypeTreeNode root=new TypeTreeNode();
        int rootId;
        if(rootIcon==schemaDatabaseIcon){
            rootId=fieldRootNodeId;
            root.set_order(fieldRootNodeId);
        }else {
            rootId=0;
        }
        root.setId(rootId);
        root.setText(rootNodeName);
        root.setState("open");
        root.setAttributes(schemaDatabaseName);
        root.setIconCls(rootIcon);
        nodesMap.put(root.getId(),root);

        for(BaseNode baseNode:baseNodes){
            TypeTreeNode baseTreeNode=new TypeTreeNode();
            baseTreeNode.setId(baseNode.getId());
            baseTreeNode.setText(baseNode.getName());
            baseTreeNode.setParentId(baseNode.getParentId());
            baseTreeNode.setState("open");
            if(baseNode.getOrder()==null){
                baseTreeNode.set_order(1);
            }else {
                baseTreeNode.set_order(baseNode.getOrder());
            }
            int type=baseNode.getType();
            if(type== schemaCatalogType){
                baseTreeNode.setAttributes(baseNode.getType()+"");
                baseTreeNode.setIconCls(schemaCatalogIcon);
            }else if(type==schemaDatabaseType){
                baseTreeNode.setAttributes(baseNode.getType()+"");
                baseTreeNode.setIconCls(schemaDatabaseIcon);
            }else if(type==caseCatalogType){
                baseTreeNode.setAttributes(baseNode.getType()+"");
                baseTreeNode.setIconCls(caseCatalogIcon);
            }else if(type==caseDataType){
                baseTreeNode.setAttributes(baseNode.getType()+"");
                baseTreeNode.setIconCls(caseDataIcon);
            }else if(type==fieldCatalogType){
                baseTreeNode.setAttributes(fieldCatalogName);
                baseTreeNode.setIconCls(fieldCatalogIcon);
            }else if(type==fieldFloatType){
                baseTreeNode.setAttributes(fieldFloatName);
                baseTreeNode.setIconCls(fieldFloatIcon);
            }else if(type==fieldTextType){
                baseTreeNode.setAttributes(fieldTextName);
                baseTreeNode.setIconCls(fieldTextIcon);
            }else if(type==fieldPictureType){
                baseTreeNode.setAttributes(fieldPictureName);
                baseTreeNode.setIconCls(fieldPictureIcon);
            }else if(type==fieldMatrixType){
                baseTreeNode.setAttributes(fieldMatrixName);
                baseTreeNode.setIconCls(fieldMatrixIcon);
            }else if(type==fieldAttachType){
                baseTreeNode.setAttributes(fieldAttachName);
                baseTreeNode.setIconCls(fieldAttachIcon);
            }else if(type==fieldMultiType){
                baseTreeNode.setAttributes(fieldMultiName);
                baseTreeNode.setIconCls(fieldMultiIcon);
            }else if(type==field3DType){
                baseTreeNode.setAttributes(field3DName);
                baseTreeNode.setIconCls(field3DIcon);
            }else if(type==fieldLinkType){
                baseTreeNode.setAttributes(fieldLinkName);
                baseTreeNode.setIconCls(fieldLinkIcon);
            }else if(type==fieldTimeType){
                baseTreeNode.setAttributes(fieldTimeName);
                baseTreeNode.setIconCls(fieldTimeIcon);
            }else if(type==fieldVideoType){
                baseTreeNode.setAttributes(fieldVideoName);
                baseTreeNode.setIconCls(fieldVideoIcon);
            }else{
                baseTreeNode.setAttributes(fieldCatalogName);
                baseTreeNode.setIconCls(fieldDataIcon);
            }
            nodesMap.put(baseTreeNode.getId(),baseTreeNode);
        }
        //如果是构建数据项表格，那么对子节点的排列顺序进行处理
        if(rootIcon==schemaDatabaseIcon){
            for(Map.Entry<Integer,TypeTreeNode> entry: nodesMap.entrySet()){
                TypeTreeNode node=entry.getValue();
                if(node.getId()!=rootId){
                    ArrayList<BaseTreeNode> oldList=new ArrayList<BaseTreeNode>();
                    int index=0;
                    TypeTreeNode parent=null;
                    if(nodesMap.get(node.getParentId())==null){
                        parent=root;
                    }else{
                        parent=nodesMap.get(node.getParentId());
                    }
                    oldList=parent.getChildren();
                    if(oldList.size()>0){
                        for(int i=oldList.size()-1;i>=0;i--){
                            if(oldList.get(i).get_order()<node.get_order()){
                                index=i+1;
                                break;
                            }
                        }
                    }
                    parent.getChildren().add(index,node);
                }
            }
        }else {
            //需要根据同级的节点的id或者order大小进行排序稳定树的节点先后顺序
            for (Map.Entry<Integer, TypeTreeNode> entry : nodesMap.entrySet()) {
                TypeTreeNode node = entry.getValue();
                if (node.getId() != rootId) {
                    ArrayList<BaseTreeNode> oldList = new ArrayList<BaseTreeNode>();
                    int index = 0;
                    TypeTreeNode parent = null;
                    if (nodesMap.get(node.getParentId()) == null) {
                        parent = root;
                    } else {
                        parent = nodesMap.get(node.getParentId());
                    }
                    oldList = parent.getChildren();
                    if (oldList.size() > 0) {
                        for(int i=oldList.size()-1;i>=0;i--){
                            if(oldList.get(i).getId()<node.getId()){
                                index=i+1;
                                break;
                            }
                        }
                    }
                    parent.getChildren().add(index, node);
                }
            }
        }

        for(Map.Entry<Integer,TypeTreeNode> entry:nodesMap.entrySet()){
            TypeTreeNode node=entry.getValue();
            node.nodeIsLeaf();
            if(node.isLeaf()){
                node.setState("open");
            }
        }
        if(checkedIds !=null&& checkedIds.size()>0){
            for (Map.Entry<Integer, TypeTreeNode> entry : nodesMap.entrySet()) {
                TypeTreeNode node = entry.getValue();
                if (checkedIds.contains(node.getId())) {
                    node.setChecked(true);
                }
            }
        }
        return root;
    }

     /**
     * 构建schema的树
     * @param schemaNodes
     * @return
     */
    public String buildSchemaTree(ArrayList<Schema> schemaNodes){
        ArrayList<BaseNode> baseNodes=new ArrayList<BaseNode>();
        for(int i=0;i<schemaNodes.size();i++){
            baseNodes.add(schemaNodes.get(i));
        }
        TypeTreeNode root= buildBaseTree(baseNodes,null,schemaRootName,
                schemaRootIcon);
        List<BaseTreeNode> list=new ArrayList<BaseTreeNode>();
        list.add(root);
        return new Gson().toJson(list);
    }


    /**
     * 构建field的树结构
     * @param fieldNodes
     * @param databaseName
     * @return
     */
    public String buildFieldTree(ArrayList<Field> fieldNodes,String databaseName){
        ArrayList<BaseNode> baseNodes=new ArrayList<BaseNode>();
        for(int i=0;i<fieldNodes.size();i++){
            baseNodes.add(fieldNodes.get(i));
        }
        TypeTreeNode root= buildBaseTree(baseNodes,null,databaseName,schemaDatabaseIcon);
        ArrayList<BaseTreeNode> list=new ArrayList<BaseTreeNode>();
        list.add(root);
        return new Gson().toJson(list);
    }


    /**
     * 构建group的树结构
     * @param groupNodes
     * @return
     */
    public TypeTreeNode buildGroupTree(ArrayList<UserGroup> groupNodes){
        ArrayList<BaseNode> baseNodes=new ArrayList<BaseNode>();
        for(int i=0;i<groupNodes.size();i++){
            baseNodes.add(groupNodes.get(i));
        }
        TypeTreeNode root= buildBaseTree(baseNodes,null,groupRootName,
                schemaRootIcon);
        return root;
    }
    /**
     * 創建用戶信息表格
     * @param users
     * @param userGroupMapper
     * @return
     */
    public static List<UserNode> buildUserGrid(List<User> users, UserGroupMapper userGroupMapper){
        List<UserNode> userNodes=new ArrayList<UserNode>();
        for(int i=0;i<users.size();i++) {
            UserNode un = new UserNode();
            un.setId(users.get(i).getId());
            un.setUserName(users.get(i).getUserName());
            un.setRoleId((users.get(i).getRoleId())==null?0:(users.get(i).getRoleId()));
            un.setGroupId((users.get(i).getGroupId())==null?0:(users.get(i).getGroupId()));
            UserGroup group = userGroupMapper.selectByPrimaryKey(un.getGroupId());
            if(group != null)
                un.setGroupName(group.getName());
            userNodes.add(un);
        }
        return userNodes;
    }

    public TypeTreeNode buildCaseTree(List<BaseNode> caseNodes, List<Integer> checkIds) {
        ArrayList<BaseNode> baseNodes = new ArrayList<BaseNode>();
        for (int i = 0; i < caseNodes.size(); i++) {
            baseNodes.add(caseNodes.get(i));
        }
        if(checkIds==null)
            return buildBaseTree(baseNodes, null, schemaRootName, schemaRootIcon);
        else
            return buildBaseTree(baseNodes, checkIds, schemaRootName, schemaRootIcon);
    }

    public TypeTreeNode buildDataTree(List<Field> nodes, String databaseName) {
        ArrayList<BaseNode> baseNodes = new ArrayList<BaseNode>();
        for (int i = 0; i < nodes.size(); i++) {
            baseNodes.add(nodes.get(i));
        }
        return buildBaseTree(baseNodes, null, databaseName, schemaDatabaseIcon);
    }

    public CaseDataTreeNode buildCaseDataTree(List<Field> baseNodes, List<Integer> checkedIds, String rootNodeName,
                                      String rootIcon, List<TableWithBLOBs> valueList) {
        Logger log = Logger.getLogger(WebFrontHelper.class);

        Map<Integer, TypeTreeNode> nodesMap = new LinkedHashMap<Integer, TypeTreeNode>();
        CaseDataTreeNode root = new CaseDataTreeNode();
        root.setId(0);
        root.setText(rootNodeName);
        root.setState("open");
        root.setAttributes(" ");
        root.setIconCls(rootIcon);
        nodesMap.put(root.getId(), root);
        Map<Integer, String> valueMap = new HashMap<Integer, String>();
        Map<Integer, String> remarkMap = new HashMap<Integer, String>();
        Map<Integer, String> unitMap = new HashMap<Integer, String>();
        for(TableWithBLOBs rec : valueList){
            valueMap.put(rec.getFieldId(),rec.getValue());
            remarkMap.put(rec.getFieldId(), rec.getRemark3());
            unitMap.put(rec.getFieldId(), rec.getRemark2());
        }
        for (int i=0;i<baseNodes.size();i++) {
            BaseNode baseNode = baseNodes.get(i);
            CaseDataTreeNode baseTreeNode = new CaseDataTreeNode();
            baseTreeNode.setId(baseNode.getId());
            baseTreeNode.setText(baseNode.getName());
            baseTreeNode.setParentId(baseNode.getParentId());
            baseTreeNode.setState("closed");

            //设置value值,hidden
            baseTreeNode.setValue_hidden(valueMap.get(baseNode.getId()));
            //设置remark_hidden
            String remark = remarkMap.get(baseNode.getId());
            if(remark==null){
                remark = "";
                baseTreeNode.setRemark_hidden(remark);
            }else{
                baseTreeNode.setRemark_hidden(remark);
                //抽取正文
                String regex = "<.+?>";
                Pattern p = Pattern.compile(regex, Pattern.DOTALL);
                Matcher m = p.matcher(remark);
                remark = m.replaceAll("");
            }
            //设置remark
            if(remark.length()>10){
                remark = remark.substring(0,10)+"...";
            }
            baseTreeNode.setRemark(remark);
            int type=baseNode.getType();
            if(type== schemaCatalogType){
                baseTreeNode.setAttributes(baseNode.getType()+"");
                baseTreeNode.setIconCls(schemaCatalogIcon);
            }else if(type==schemaDatabaseType){
                baseTreeNode.setAttributes(baseNode.getType()+"");
                baseTreeNode.setIconCls(schemaDatabaseIcon);
            }else if(type==caseCatalogType){
                baseTreeNode.setAttributes(baseNode.getType()+"");
                baseTreeNode.setIconCls(caseCatalogIcon);
            }else if(type==caseDataType){
                baseTreeNode.setAttributes(baseNode.getType()+"");
                baseTreeNode.setIconCls(caseDataIcon);
            }else if(type==fieldCatalogType){
                baseTreeNode.setAttributes(fieldCatalogName);
                baseTreeNode.setIconCls(fieldCatalogIcon);
            }else if(type==fieldFloatType){
                //设置value值,显示
                String val = valueMap.get(baseNode.getId());
                if(val!=null&&!val.equals("") && unitMap.get(baseNode.getId())!=null){
                    val = val + "      " +unitMap.get(baseNode.getId());
                }
                baseTreeNode.setData_value(val);
                baseTreeNode.setAttributes(fieldFloatName);
                baseTreeNode.setIconCls(fieldFloatIcon);
            }else if(type==fieldTextType){
                //设置value值,显示
                String val = valueMap.get(baseNode.getId());
                if(val!=null&&val.length()>10){
                    val = val.substring(0,10)+"...";
                }
                baseTreeNode.setData_value(val);
                baseTreeNode.setAttributes(fieldTextName);
                baseTreeNode.setIconCls(fieldTextIcon);
            }else if(type==fieldPictureType){
                //设置value值,显示
                String val = valueMap.get(baseNode.getId());
                if(val!=null&&val.length()>10){
                    val = val.substring(1,10)+"...";
                }
                baseTreeNode.setData_value(val);
                baseTreeNode.setAttributes(fieldPictureName);
                baseTreeNode.setIconCls(fieldPictureIcon);
            }else if(type==fieldMatrixType){
                //设置value值,显示
                String val = valueMap.get(baseNode.getId());
                if(val!=null&&val.length()>10){
                    val = val.substring(0,10)+"...";
                }
                baseTreeNode.setData_value(val);
                baseTreeNode.setAttributes(fieldMatrixName);
                baseTreeNode.setIconCls(fieldMatrixIcon);
            }else if(type==fieldAttachType){
                //设置value值,显示
                String val = valueMap.get(baseNode.getId());
                if(val!=null&&val.length()>10){
                    val = val.substring(1,10)+"...";
                }
                baseTreeNode.setData_value(val);
                baseTreeNode.setAttributes(fieldAttachName);
                baseTreeNode.setIconCls(fieldAttachIcon);
            }else if(type==fieldMultiType){
                //设置value值,显示
                String val = valueMap.get(baseNode.getId());
                //抽取正文
                String regex = "<.+?>";
                Pattern p = Pattern.compile(regex, Pattern.DOTALL);
                Matcher m = p.matcher(val);
                val = m.replaceAll("");
                if(val!=null&&val.length()>10){
                    val = val.substring(0,10)+"...";
                }
                baseTreeNode.setData_value(val);
                baseTreeNode.setAttributes(fieldMultiName);
                baseTreeNode.setIconCls(fieldMultiIcon);
            }else if(type==field3DType){
                //设置value值,显示
                String val = valueMap.get(baseNode.getId());
                if(val!=null&&val.length()>10){
                    val = val.substring(1,10)+"...";
                }
                baseTreeNode.setData_value(val);
                baseTreeNode.setAttributes(field3DName);
                baseTreeNode.setIconCls(field3DIcon);
            }else if(type==fieldLinkType){
                //设置value值,显示
                String val = valueMap.get(baseNode.getId());
                if(val!=null&&val.length()>10){
                    val = val.substring(0,10)+"...";
                }
                baseTreeNode.setData_value(val);
                baseTreeNode.setAttributes(fieldLinkName);
                baseTreeNode.setIconCls(fieldLinkIcon);
            }else if(type==fieldTimeType){
                //设置value值,显示
                String val = valueMap.get(baseNode.getId());
                baseTreeNode.setData_value(val);
                baseTreeNode.setAttributes(fieldTimeName);
                baseTreeNode.setIconCls(fieldTimeIcon);
            }else if(type==fieldVideoType){
                //设置value值,显示
                String val = valueMap.get(baseNode.getId());
                if(val!=null&&val.length()>10){
                    val = val.substring(1,10)+"...";
                }
                baseTreeNode.setData_value(val);
                baseTreeNode.setAttributes(fieldVideoName);
                baseTreeNode.setIconCls(fieldVideoIcon);
            }else if(type==field3MatrixType){
                //设置value值,显示
                String val = valueMap.get(baseNode.getId());
                if(val!=null&&val.length()>10){
                    val = val.substring(0,10)+"...";
                }
                baseTreeNode.setData_value(val);
                baseTreeNode.setAttributes(field3MatrixName);
                baseTreeNode.setIconCls(field3MatrixIcon);
            }else{
                baseTreeNode.setAttributes(fieldCatalogName);
                baseTreeNode.setIconCls(fieldDataIcon);
            }
            nodesMap.put(baseTreeNode.getId(), baseTreeNode);
        }
        for (Map.Entry<Integer, TypeTreeNode> entry : nodesMap.entrySet()) {
            TypeTreeNode node = entry.getValue();
            if (node.getId() != 0) {
                if (nodesMap.get(node.getParentId()) == null) {
                    root.addChild(node);
                } else {
                    nodesMap.get(node.getParentId()).addChild(node);
                }
            }
        }

        for (Map.Entry<Integer, TypeTreeNode> entry : nodesMap.entrySet()) {
            TypeTreeNode node = entry.getValue();
            node.nodeIsLeaf();
            if (node.isLeaf()) {
                node.setState("open");
            }
        }
        if (checkedIds != null && checkedIds.size() > 0) {
            for (Map.Entry<Integer, TypeTreeNode> entry : nodesMap.entrySet()) {
                TypeTreeNode node = entry.getValue();
                if (checkedIds.contains(node.getId())) {
                    node.setChecked(true);
                }
            }
        }
        return root;
    }


}
